package runze.shiro.security;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import runze.shiro.domain.Role;
import runze.shiro.domain.User;
import runze.shiro.service.UserService;

/**
 * @author wrzhxy@qq.com
 * @date 2017年12月28日
 */
@Component
public class SampleRealm extends AuthorizingRealm {

	@Autowired
    protected UserService userService;

    public SampleRealm() {
System.out.println("SampleRealm setName");
        setName("SampleRealm");		//This name must match the name in the User class's getPrincipals() method
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("SHA-256");
        setCredentialsMatcher(hashedCredentialsMatcher);
    }
    
    /**
     * 授权验证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("授权验证");
		//获取当前登录输入的用户名，等价于(String) principalCollection.fromRealm(getName()).iterator().next();
		String loginName = (String)super.getAvailablePrincipal(principals);
		// 到数据库查是不是有此对象
		User user = userService.getUser(loginName);
System.out.println("login name: " + loginName);		
		if (user != null) {
			// 权限信息对象info，用来存放查出的用户的所有角色和权限
			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
			// 用户的角色集合
			Set<String> roles = new HashSet<>();
			Set<Role> roles_db = user.getRoles();
			for (Role r : roles_db) {
				roles.add(r.getName());
				// 用户的角色对应的所有权限，如果只使用角色定义访问权限，下面可以不要
				// 遍历角色，获取权限
//				info.addStringPermission("fuck:666");
				info.addStringPermissions(r.getPermissions());	// 会将整个集合添加到
			}
			info.setRoles(roles);
System.out.println("authorization finished");
			return info;
		} else return null;
    }
    
    /**
     * 登录验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("登录验证");    	
    	// UsernamePasswordToken对象用来存放提交的登录信息
        UsernamePasswordToken upt = (UsernamePasswordToken) token;
        
        // 查出是否有此用户
        String username_upt = upt.getUsername();
        User user = userService.getUser(username_upt);
        
        if (user != null) {
        	// 若存在，将此用户存放到登录认证info中，无需自己做密码对比，Shiro会为我们进行密码对比校验
            return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
        }
    	return null;
    }

}
